package cn.good.yan.service.t7;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;

/**
 * 7. 原子类
 * AtomicReferenceFieldUpdater<T>   原子引用类 ，对于一个类的，某个字段（需要保持原子性）某个方法，对该值操作
 *
 * @author shengren.yan
 * @create 2024-04-02
 */
public class AtomicDemo5 {

    public static void main(String[] args) {
        MyVar myVar = new MyVar();
        // 开启5个线程，只有一个线程初始化成功，其他线程不能初始化操作，保证原子性
        for (int i = 1; i <= 5; i++) {
            new Thread(() -> {
                myVar.init(myVar);
            }, String.valueOf(i)).start();
        }
    }

}

// 资源类
class MyVar {

    // 某个字段
    private volatile Boolean isInit = Boolean.FALSE;
    // AtomicReferenceFieldUpdater ,它是原子引用
    AtomicReferenceFieldUpdater<MyVar, Boolean> referenceField =
            AtomicReferenceFieldUpdater.newUpdater(MyVar.class, Boolean.class, "isInit");

    // 初始化 - 方法
    public void init(MyVar myVar) {
        // 比较并交换，参数1：哪个对象，参数2：期望值，参数3：要更改的值，【把状态改为 true】
        if (referenceField.compareAndSet(myVar, Boolean.FALSE, Boolean.TRUE)) {
            System.out.println(Thread.currentThread().getName() + "\t" + "----- 当前线程抢到锁 -- 并执行逻辑。。。");
            // 暂停几秒钟线程
            try {
                TimeUnit.SECONDS.sleep(3);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "\t" + "----- 当前线程抢到锁 -- 执行完。。。");
        } else {
            System.out.println(Thread.currentThread().getName() + "\t" + "----- 已经有线程在进行初始化工作。。。。。");
        }
    }

}
